'''
A simple self-ping-pong application.

@author: oraby
'''
import sys
import time

from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, ClientCreator, ServerFactory
from twisted.protocols.basic import LineOnlyReceiver


class Data:
    pingLimit = 500
    
class PingServer(LineOnlyReceiver):
    def lineReceived(self, line):
        self._count += 1
        line = "Pong " + str(self._count)
        #print line
        self.sendLine(line)
        if self._count == Data.pingLimit:
            #print "Loosing Connection."
            self.transport.loseConnection()
    
    def connectionMade(self):
        self._count = 0
        
class  PingServerFactory(ServerFactory):
    protocol = PingServer


class PingClient(LineOnlyReceiver):

    def lineReceived(self, line):
        self._count += 1
        line = "Ping " + str(self._count)
        #print line
        self.sendLine(line)
        if self._count == Data.pingLimit:
            self.transport.loseConnection()

    def connectionMade(self):
        self._startTime = time.time()
        self._count = 1
        line = "Ping " + str(self._count)
        self.sendLine(line)
        
    def connectionLost(self, reason):
        #print reason
        timeDiff = time.time() - self._startTime
        print "Made", self._count, "ping @Time= " + repr(timeDiff)





def peerConnSucc(Connector):
    #print "Connection to Peer established"
    pass

def peerConnFailed(reason):
    print "Connection to peer Failed"
    print "Reason: " + str(reason)

def main():
    #Start listening
    reactor.listenTCP(2000,PingServerFactory())
    pinger = ClientCreator(reactor, PingClient)
    d = pinger.connectTCP('127.0.0.1', 2000)
    d.addCallbacks(callback = peerConnSucc, errback = peerConnFailed)
    reactor.run()

    
if __name__ == '__main__':
    main()